/* (c) 2013 Fyren, see license.txt */

#pragma once

#include <iostream>
#include <vector>
#include <map>
#include <random>
#include <algorithm>

void initWhatiah();
static void initCharms();
static void initMobs();

enum CharmID
{
	woodenSword,
	ratFlail,
	largeBone,
	sparkWand,
	smallIceWand,
	bronzeHelm,
	leatherPants,
	wornLeatherChest,
	shoulderGlyph,
	glyphedGloves,
	smallGlyph,
	ratCloak,
	goblinPunch,
	lightDust,
	shell,
	sparkles,
	pairOfStoneSwords,
	darknessWand,
	smallFlameWand,
	heatWand,
	frostWand,
	numCharms,
	noCharm
};

enum MobID
{
	oldGoblin,
	prairieSprite,
	numMobs
};

class Charm
{
	public:
	int a;
	int w;
	int cA;
	int cW;
	int pD;
	int pP;
	int mD;
	int mP;

	CharmID id;
	const char *name;
	Charm(CharmID id_ = noCharm, const char* n = NULL);
	Charm* arm(int a);
	Charm* ward(int w);
	Charm* cArm(int cA);
	Charm* cWard(int cW);
	Charm* pDam(int pD);
	Charm* pPen(int pP);
	Charm* mDam(int mD);
	Charm* mPen(int mP);
	friend std::ostream& operator<<(std::ostream &out, Charm &ch);
};

typedef std::vector<Charm*> Deck;

class Mob
{
	public:
	Deck deck;
	int maxHP;
	int HP;
	int maxSP;
	int SP;
	int a;
	int w;

	bool alive;
	Deck::iterator it;

	const char *name;
	void init(bool shuffle_ = true);
	void shuffle();
	void inflict(Charm *ch);
	void apply(Charm *ch);
	bool checkAlive();
	Charm* draw();
	Mob(const char *n, int HP_, Deck d, bool shuffle_ = true);
	friend std::ostream& operator<<(std::ostream &out, Mob &m);
};

typedef std::vector<Mob*> Mobs;

extern std::map<CharmID, Charm*> charms;
extern std::map<MobID, Mob*> mobs;
extern std::mt19937 *mt;

class Fight
{
	public:
	Mobs team1;
	Mobs team2;
	int turn;
	Fight(Mobs t1, Mobs t2);
	void initMobs();
	void start(bool print = false);
	bool teamsAlive();
	Mobs getTeam(Mob *m);
	Mobs getOtherTeam(Mob *m);
	Mob* getRandomMob(Mobs m);
	void nextMob(Mobs::iterator begin, Mobs::iterator end, Mobs::iterator &it);
};
